﻿using SharpDX;
using SharpDX.Direct2D1;
using System;
using System.Collections.Generic;
using System.Text;

namespace SpaceBattle
{
    class Asteroid
    {
        // object attributes
        public Vector2 MovementVector;
        private float MaxSpeed = 30;
        public float Speed; // pixels per second
        private float MaxSize = 40.0f;

        // drawing attributes
        private DrawingPointF [] Points = new DrawingPointF[4];
        private DrawingPointF Center = new DrawingPointF();

        // dx - specific
        RenderTarget renderTarget;
        Factory factory;
        PathGeometry Geometry = null;

        public Asteroid(RenderTarget renderTarget, Factory factory, Random rng)
        {
            this.renderTarget = renderTarget;
            this.factory = factory;

            // Generate geometry
            if (rng.NextDouble() < 0.5)
            {
                Center.X = -MaxSize + MaxSize * (float)rng.NextDouble();
            }
            else
            {
                Center.X = renderTarget.PixelSize.Width + MaxSize * (float)rng.NextDouble();
            }

            if (rng.NextDouble() < 0.5)
            {
                Center.Y = -MaxSize + MaxSize * (float)rng.NextDouble();
            }
            else
            {
                Center.Y = renderTarget.PixelSize.Height + MaxSize * (float)rng.NextDouble();
            }
            
            Center.Y = renderTarget.PixelSize.Height * (float)rng.NextDouble();

            Points[0] = new DrawingPointF(Center.X - MaxSize / 2 * (float)rng.NextDouble(),
                Center.Y - MaxSize / 2 * (float)rng.NextDouble());
            Points[1] = new DrawingPointF(Center.X + MaxSize / 2 * (float)rng.NextDouble(),
                Center.Y - MaxSize / 2 * (float)rng.NextDouble());
            Points[2] = new DrawingPointF(Center.X + MaxSize / 2 * (float)rng.NextDouble(),
                Center.Y + MaxSize / 2 * (float)rng.NextDouble());
            Points[3] = new DrawingPointF(Center.X - MaxSize / 2 * (float)rng.NextDouble(),
                Center.Y + MaxSize / 2 * (float)rng.NextDouble());

            //Generate parameters
            MovementVector = new Vector2(-1 + 2 * (float)rng.NextDouble(), -1 + 2 * (float)rng.NextDouble());
            MovementVector.Normalize();

            Speed = MaxSpeed * (float)rng.NextDouble();

            GenerateGeometry();
        }

        private void GenerateGeometry()
        {
            Geometry = new PathGeometry(factory);
            var geometrySink = Geometry.Open();
            geometrySink.BeginFigure(Points[0], FigureBegin.Filled);
            geometrySink.AddLine(Points[1]);
            geometrySink.AddLine(Points[2]);
            geometrySink.AddLine(Points[3]);
            geometrySink.EndFigure(FigureEnd.Closed);
            geometrySink.Close();
        }

        public DrawingPointF GetCenter()
        {
            return Center;
        }

        private void SetCenter(DrawingPointF newCenter)
        {
            for (int i = 0; i < 4; i++)
            {
                Points[i] = new DrawingPointF(Points[i].X - Center.X + newCenter.X,
                    Points[i].Y - Center.Y + newCenter.Y);
            }

            Center = newCenter;

            Geometry.Dispose();
            GenerateGeometry();
        }

        public void Update(float dt)
        {
            SetCenter(Center + MovementVector * Speed * dt);
        }

        public void Draw(SolidColorBrush brush)
        {
            renderTarget.FillGeometry(Geometry, brush);
            renderTarget.DrawGeometry(Geometry, brush);
        }

        public bool IsOutOfView()
        {
            return (Center.X < (-MaxSize*2) || Center.X > (renderTarget.Size.Width + MaxSize*2)) ||
                (Center.Y < (-MaxSize*2) || Center.Y > (renderTarget.Size.Height + MaxSize*2));
        }
    }
}
